package com.example.yin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.yin.common.R;
import com.example.yin.common.SongMapDetailDTO;
import com.example.yin.controller.MinioUploadController;
import com.example.yin.mapper.SongMapper;
import com.example.yin.model.domain.Song;
import com.example.yin.model.request.SongRequest;
import com.example.yin.service.SongService;
import com.example.yin.utils.HttpClientUtils;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {

    @Autowired
    private SongMapper songMapper;

    @Value("${minio.bucket-name}")
    private String bucketName;

    @Autowired
    MinioClient minioClient;

    @Override
    public R allSong() {
        return R.success(null, songMapper.selectList(null));
    }

    @Override
    public R addSong(SongRequest addSongRequest, MultipartFile lrcfile,MultipartFile mpfile){
        Song song = new Song();
        BeanUtils.copyProperties(addSongRequest, song);
        String pic = "/img/songPic/tubiao.jpg";
        String fileName = mpfile.getOriginalFilename();
        String s = MinioUploadController.uploadFile(mpfile);
        String storeUrlPath = "/"+bucketName+"/" + fileName;
        song.setCreateTime(new Date());
        song.setUpdateTime(new Date());
        song.setPic(pic);
        song.setUrl(storeUrlPath);

        if (lrcfile!=null&&(song.getLyric().equals("[00:00:00]暂无歌词"))){
            byte[] fileContent = new byte[0];
            try {
                fileContent = lrcfile.getBytes();
                String content = new String(fileContent, "GB2312");
                song.setLyric(content);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        if (s.equals("File uploaded successfully!")&&songMapper.insert(song) > 0) {
            return R.success("上传成功", storeUrlPath);
        } else {
            return R.error("上传失败");
        }
    }

    @Override
    public R updateSongMsg(SongRequest updateSongRequest) {
        Song song = new Song();
        BeanUtils.copyProperties(updateSongRequest, song);
        if (songMapper.updateById(song) > 0) {
            return R.success("修改成功");
        } else {
            return R.error("修改失败");
        }
    }

    @Override
    public R updateSongUrl(MultipartFile urlFile, int id) {
        Song song = songMapper.selectById(id);
        String path = song.getUrl();
        String[] parts = path.split("/");
        String fileName = parts[parts.length - 1];

        RemoveObjectArgs removeObjectArgs=RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .build();
        fileName = urlFile.getOriginalFilename();
        String s = MinioUploadController.uploadFile(urlFile);
        try {
            minioClient.removeObject(removeObjectArgs);
        } catch (ErrorResponseException e) {
            throw new RuntimeException(e);
        } catch (InsufficientDataException e) {
            throw new RuntimeException(e);
        } catch (InternalException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (InvalidResponseException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (ServerException e) {
            throw new RuntimeException(e);
        } catch (XmlParserException e) {
            throw new RuntimeException(e);
        }
        String storeUrlPath = "/"+bucketName+"/" + fileName;
        song.setId(id);
        song.setUrl(storeUrlPath);
        song.setName(fileName);
        if (s.equals("File uploaded successfully!")&&songMapper.updateById(song) > 0) {
            return R.success("更新成功", storeUrlPath);
        } else {
            return R.error("更新失败");
        }
    }

    @Override
    public R updateSongPic(MultipartFile urlFile, int id) {
        String fileName =  urlFile.getOriginalFilename();
        String storeUrlPath = "/user01/singer/song/" + fileName;
        MinioUploadController.uploadSongImgFile(urlFile);
        Song song = new Song();
        song.setId(id);
        song.setPic(storeUrlPath);
        if (songMapper.updateById(song) > 0) {
            return R.success("上传成功", storeUrlPath);
        } else {
            return R.error("上传失败");
        }
    }

    @Override
    public R deleteSong(Integer id) {
        Song song = songMapper.selectById(id);
        String path = song.getUrl();
        String[] parts = path.split("/");
        String fileName = parts[parts.length - 1];
        System.out.println(fileName);
        RemoveObjectArgs removeObjectArgs=RemoveObjectArgs.builder()
                .bucket(bucketName)
                .object(fileName)
                .build();
        if (songMapper.deleteById(id) > 0) {
            try {
                minioClient.removeObject(removeObjectArgs);
            } catch (ErrorResponseException e) {
                throw new RuntimeException(e);
            } catch (InsufficientDataException e) {
                throw new RuntimeException(e);
            } catch (InternalException e) {
                throw new RuntimeException(e);
            } catch (InvalidKeyException e) {
                throw new RuntimeException(e);
            } catch (InvalidResponseException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            } catch (ServerException e) {
                throw new RuntimeException(e);
            } catch (XmlParserException e) {
                throw new RuntimeException(e);
            }
            return R.success("删除成功");
        } else {
            return R.error("删除失败");
        }
    }

    @Override
    public R songOfSingerId(Integer singerId) {
        QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("singer_id",singerId);
        return R.success(null, songMapper.selectList(queryWrapper));
    }
    @Override
    public R songOfMap(String mapKey) {
        try {
            // 拼接请求参数（keywords=mapKey）
            String url = "http://localhost:3000/search/complex";
            Map<String, Object> params = new HashMap<>();
            params.put("keywords", mapKey); // 参数名需与接口一致

            // 调用 HttpClientUtils 的 sendGet 方法
            String response = HttpClientUtils.sendGet(url, params);
            System.out.println("此时response为"+response);

            //解析Json
            JSONObject jsonObject=JSON.parseObject(response);
            JSONArray dataLists = jsonObject.getJSONObject("data").getJSONArray("lists");
            List<String> fileHashList = new ArrayList<>();
            for(Object listItem:dataLists){
                JSONObject listObj=(JSONObject) listItem;
                JSONArray songs = listObj.getJSONArray("lists");
                for(Object songItem:songs){
                    JSONObject songObj=(JSONObject) songItem;
                    String fileHash=songObj.getString("FileHash");
                    if(fileHash!=null && !fileHash.isEmpty()){
                        fileHashList.add(fileHash);
                    }
                }

            }
            System.out.println("获取的hashList"+fileHashList);

            // 请求成功但无数据
            return R.success("请求歌曲hash成功",fileHashList);

        } catch (Exception e) {
            // 处理异常
            log.error("调用搜索接口失败：", e);
            return null;
        }
    }

    @Override
    public R songOfMapDetail(String hash) {
        // 封装数据

        SongMapDetailDTO songMapDetailDTO=new SongMapDetailDTO();
        try{

            // 1. 构造请求参数
            String url = "http://localhost:3000/song/url";
            url=url+"?hash="+hash+"&=";
            String response=HttpClientUtils.sendGet(url);
            JSONObject jsonObject=JSON.parseObject(response);
            long timestamp=System.currentTimeMillis();
            songMapDetailDTO.setId(null);// 歌曲id null
            songMapDetailDTO.setSingerId(null);//  歌手id
            songMapDetailDTO.setName(jsonObject.getString("fileName"));
            songMapDetailDTO.setIntroduction(null);  //介绍 null
            songMapDetailDTO.setCreateTime(String.valueOf(timestamp));
            songMapDetailDTO.setUpdateTime(String.valueOf(timestamp));
            songMapDetailDTO.setPic(jsonObject.getJSONObject("trans_param").getString("union_cover"));
            songMapDetailDTO.setLyric(null);
            songMapDetailDTO.setUrl(jsonObject.getJSONArray("url").get(0).toString());

            String songDetailUrl="http://localhost:3000/images";
            songDetailUrl=songDetailUrl+"?hash="+hash;
            String response2=HttpClientUtils.sendGet(songDetailUrl);
            JSONObject songDetailJsonObject = JSON.parseObject(response2);
            // 获取歌手图片
            String singerPicUrl = songDetailJsonObject.getJSONArray("data")
                    .getJSONObject(0)
                    .getJSONArray("author")
                    .getJSONObject(0)
                    .getJSONObject("imgs")
                    .getJSONArray("3")
                    .getJSONObject(0)
                    .getString("sizable_portrait");
            songMapDetailDTO.setPic(singerPicUrl);
            // 获取歌手名字
            String singerName=songDetailJsonObject.getJSONArray("data")
                    .getJSONObject(0)
                    .getJSONArray("author")
                    .getJSONObject(0)
                    .getString("author_name");
            songMapDetailDTO.setSingerName(singerName);

            return R.success("成功",songMapDetailDTO);
        }catch (Exception e){
            return null;
        }


    }

    @Override
    public R songOfId(Integer id) {
        QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        System.out.println(id);
        System.out.println(songMapper.selectList(queryWrapper));
        return R.success(null, songMapper.selectList(queryWrapper));
    }

    @Override
    public R songOfSingerName(String name) {
        QueryWrapper<Song> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name",name);
        List<Song> songs = songMapper.selectList(queryWrapper);
        if (songs.isEmpty()){
            return R.error("添加失败，没有找到该歌,无法加入该歌单");
        }

        return R.success(null, songMapper.selectList(queryWrapper));
    }

    @Override
    public R updateSongLrc(MultipartFile lrcFile, int id) {
        Song song = songMapper.selectById(id);
        if (lrcFile!=null&&!(song.getLyric().equals("[00:00:00]暂无歌词"))){
            byte[] fileContent = new byte[0];
            try {
                fileContent = lrcFile.getBytes();
                String content = new String(fileContent, "GB2312");
                song.setLyric(content);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        if (songMapper.updateById(song) > 0) {
            return R.success("更新成功");
        } else {
            return R.error("更新失败");
        }
    }


}
